package servlet;

import java.io.IOException;
import java.net.URLEncoder;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.smartam.leeloo.as.issuer.MD5Generator;
import net.smartam.leeloo.as.issuer.OAuthIssuer;
import net.smartam.leeloo.as.issuer.OAuthIssuerImpl;
import net.smartam.leeloo.client.OAuthClient;
import net.smartam.leeloo.client.URLConnectionClient;
import net.smartam.leeloo.client.request.OAuthClientRequest;
import net.smartam.leeloo.client.response.GitHubTokenResponse;
import net.smartam.leeloo.common.OAuth;
import net.smartam.leeloo.common.message.types.GrantType;
import util.Logger;
import util.SamlRequest;
import constant.Constant;

//http://open.weibo.com/wiki/Oauth2

/**
 * Servlet implementation class AuthnServlet
 */
@WebServlet(Constant.DEFAULT_AUTHSERVER)
public class AuthnServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * Default constructor.
	 */
	public AuthnServlet() {
		// TODO Auto-generated constructor stub
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		Logger.Log("AuthN Server...");

		Logger.Log("User " + request.getParameter(Constant.SYNC_USER));
		if (request.getParameter(Constant.SYNC_USER) == null) {
			request.getRequestDispatcher("/Login.jsp").forward(request,
					response);
			return;
		}

		try {


			String client_id = request.getParameter(OAuth.OAUTH_CLIENT_ID);
			String client_secret = request
					.getParameter(OAuth.OAUTH_CLIENT_SECRET);
			Logger.Log("client_id " + client_id);
			Logger.Log("client_secret " + client_secret);

			OAuthIssuer oauthIssuerImpl = new OAuthIssuerImpl(
					new MD5Generator());

			String code = oauthIssuerImpl.authorizationCode();
			String redirectURI = request.getParameter(OAuth.OAUTH_REDIRECT_URI);// Constant.DEFAULT_URL_RESOURCESERVER;//"/Application.jsp";

			Logger.Log("redirectURI " + redirectURI);
			// String accessToken = oauthIssuerImpl.accessToken();
			// String refreshToken = oauthIssuerImpl.refreshToken();

			OAuthClientRequest oauthreq = OAuthClientRequest
					.tokenLocation(
							this.getAccessTokenURI(request))
					.setGrantType(GrantType.AUTHORIZATION_CODE)
					.setClientId(client_id)
					.setClientSecret(client_secret)
					.setRedirectURI(
							this.getResourceServerURI(request))
					.setCode(code).buildBodyMessage();

			// create OAuth client that uses custom http client under the hood
			OAuthClient oAuthClient = new OAuthClient(new URLConnectionClient());


			GitHubTokenResponse oAuthResponse = oAuthClient.accessToken(
					oauthreq, GitHubTokenResponse.class);

			String accessToken = oAuthResponse.getAccessToken();
			String expiresIn = oAuthResponse.getExpiresIn();

			String issuer = request.getParameter(Constant.SYNC_AP);
			Logger.Log("accessToken " + accessToken + " expiresIn " + expiresIn);
			Logger.Log("issuer " + issuer);

			String callback = request.getParameter(OAuth.OAUTH_REDIRECT_URI)
					+ "?"
					+"&"+OAuth.OAUTH_ACCESS_TOKEN+"="+ URLEncoder.encode(
					 this.generateSamlToken(issuer, accessToken),"utf-8")
			;

			Logger.Log("callback uri " + callback);

			response.setStatus(Constant.STATUSCODE_OAUTH);

			response.addHeader("Location", callback);

		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	private String generateSamlToken(String issuer, String access_token)
			throws Exception {
		return SamlRequest.request(issuer, access_token);
	}
	private String getResourceServerURI(HttpServletRequest request){
		return request.getParameter(OAuth.OAUTH_REDIRECT_URI);//Constant.HOST_LOCAL + Constant.DEFAULT_URL_RESOURCESERVER;
	}	
	private String getAccessTokenURI(HttpServletRequest request){
		return Constant.HOST_LOCAL
				+ Constant.DEFAULT_URL_ACCESSTOKEN;
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		this.doGet(request, response);
	}

}
